package com.gitee.linzl.zuul.gateway.fiters.pre;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.io.Resource;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.util.UrlPathHelper;

import com.gitee.linzl.zuul.gateway.ZuulPropertiesExt;
import com.gitee.linzl.zuul.gateway.fiters.AbstractDefaultPreFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * 静态资源的过滤，直接返回资源内容：如js,html,png等
 * 
 * 目前起不到任何作用,暂时没有想到解决方案
 * 
 * @description
 * @author linzl
 * @email 2225010489@qq.com
 * @date 2018年10月24日
 */
// @Component
@Slf4j
@Setter
@Getter
public class StaticResourceFilter extends AbstractDefaultPreFilter {
	private PathMatcher pathMatcher = new AntPathMatcher();
	private UrlPathHelper urlPathHelper = new UrlPathHelper();
	@Autowired
	private ZuulPropertiesExt zuulPropertiesExt;
	@Autowired
	private ApplicationContext context;
	@Autowired
	private ResourceProperties resourceProperties;

	@Override
	public int filterOrder() {
		return 0;
	}

	private List<ViewResolver> viewResolvers;
	protected static final String STATIC_RESOURCE_FILTER_RAN = "staticResourceFilter.ran";

	@Override
	public boolean shouldFilter() {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);

		Set<String> staticResource = null;
		if ((staticResource = zuulPropertiesExt.getStaticResource()) != null) {
			for (String staticResourcePath : staticResource) {
				if (this.pathMatcher.match(staticResourcePath, lookupPath)) {
					return !ctx.getBoolean(STATIC_RESOURCE_FILTER_RAN, false);
				}
			}
		}
		return false;
	}

	@Override
	public Object run() throws ZuulException {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();

		// Find all ViewResolvers in the ApplicationContext, including ancestor
		// contexts.
		Map<String, ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context,
				ViewResolver.class, true, false);
		if (!matchingBeans.isEmpty()) {
			this.viewResolvers = new ArrayList<>(matchingBeans.values());
			// We keep ViewResolvers in sorted order.
			AnnotationAwareOrderComparator.sort(this.viewResolvers);
		}
		String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
		String viewName = lookupPath.substring(1);

		if ("favicon.ico".equals(viewName)) {
			return null;
		}
		log.debug("StaticResourceFilter-->lookupPath:{}", viewName);
		for (String location : this.resourceProperties.getStaticLocations()) {
			try {
				Resource resource = this.context.getResource(location);
				resource = resource.createRelative(viewName);
				if (resource.exists()) {
					ctx.set(STATIC_RESOURCE_FILTER_RAN, true);
					InputStream is = resource.getInputStream();
					setStaticResponse(is, 200);
				}
			} catch (Exception ex) {
			}
		}
		return null;
	}
}
